<template>
  <div class="circular-dependency-panel">
    <el-card class="panel-card">
      <template #header>
        <div class="panel-header">
          <div class="header-left">
            <h3>🔄 循环依赖详情分析</h3>
            <p class="header-subtitle">发现并分析项目中的循环依赖问题，提供优化建议</p>
          </div>
          <div class="header-actions">
            <el-tooltip content="刷新循环依赖数据" placement="top">
              <el-button
                type="primary"
                :icon="Refresh"
                size="small"
                @click="reload"
                :loading="loading"
              />
            </el-tooltip>
          </div>
        </div>
      </template>

      <div v-if="loading" class="loading-container">
        <el-skeleton :rows="6" animated />
      </div>

      <div v-else-if="!circularDependencies || circularDependencies.length === 0" class="no-data-container">
        <el-result
          icon="success"
          title="项目健康"
          sub-title="🎉 恭喜！项目中未发现循环依赖问题"
        >
          <template #extra>
            <el-alert
              title="良好的代码结构"
              description="没有循环依赖表示项目的依赖关系清晰，代码结构良好，易于维护和扩展。"
              type="success"
              :closable="false"
              show-icon
            />
          </template>
        </el-result>
      </div>

      <div v-else class="panel-content">
        <!-- 概览统计 -->
        <div class="overview-section">
          <div class="stats-cards">
            <el-tooltip
              effect="dark"
              content="项目中发现的循环依赖总数。每个循环依赖都需要仔细分析和解决。"
              placement="top"
              :show-after="300"
            >
              <div class="stat-card danger">
                <div class="stat-icon">⚠️</div>
                <div class="stat-info">
                  <div class="stat-value">{{ circularDependencies.length }}</div>
                  <div class="stat-label">循环依赖数</div>
                </div>
              </div>
            </el-tooltip>

            <el-tooltip
              effect="dark"
              content="被循环依赖影响的文件总数。数量越多说明问题影响范围越广。"
              placement="top"
              :show-after="300"
            >
              <div class="stat-card warning">
                <div class="stat-icon">📄</div>
                <div class="stat-info">
                  <div class="stat-value">{{ totalAffectedFiles }}</div>
                  <div class="stat-label">影响文件数</div>
                </div>
              </div>
            </el-tooltip>

            <el-tooltip
              effect="dark"
              content="高危险等级的循环依赖数量。这些依赖需要优先处理。"
              placement="top"
              :show-after="300"
            >
              <div class="stat-card severe">
                <div class="stat-icon">🚨</div>
                <div class="stat-info">
                  <div class="stat-value">{{ highSeverityCount }}</div>
                  <div class="stat-label">高危循环</div>
                </div>
              </div>
            </el-tooltip>

            <el-tooltip
              effect="dark"
              content="最长循环依赖链的长度。链越长问题越复杂，解决难度越大。"
              placement="top"
              :show-after="300"
            >
              <div class="stat-card info">
                <div class="stat-icon">🔗</div>
                <div class="stat-info">
                  <div class="stat-value">{{ maxCircularLength }}</div>
                  <div class="stat-label">最长链长</div>
                </div>
              </div>
            </el-tooltip>
          </div>
        </div>

        <!-- 循环依赖列表 -->
        <div class="circular-list-section">
          <div class="section-header">
            <h4>🔍 循环依赖详细列表</h4>
            <div class="filter-controls">
              <el-select
                v-model="selectedSeverity"
                placeholder="按危险等级筛选"
                clearable
                size="small"
                style="width: 160px;"
              >
                <el-option label="高危险" value="high" />
                <el-option label="中危险" value="medium" />
                <el-option label="低危险" value="low" />
              </el-select>

              <el-select
                v-model="selectedType"
                placeholder="按类型筛选"
                clearable
                size="small"
                style="width: 120px;"
              >
                <el-option label="文件间" value="file" />
                <el-option label="包间" value="package" />
              </el-select>
            </div>
          </div>

          <div class="circular-items">
            <div
              v-for="(circular, index) in filteredCircularDependencies"
              :key="circular.id"
              class="circular-item"
            >
              <el-card class="circular-card" :class="getSeverityClass(circular.severity)">
                <!-- 循环依赖基本信息 -->
                <div class="circular-header">
                  <div class="header-left">
                    <div class="circular-title">
                      <span class="circular-index">#{{ index + 1 }}</span>
                      <el-tag :type="getSeverityTagType(circular.severity)" size="small">
                        {{ getSeverityText(circular.severity) }}
                      </el-tag>
                      <el-tag :type="getTypeTagType(circular.type)" size="small">
                        {{ getTypeText(circular.type) }}
                      </el-tag>
                      <span class="circular-length">{{ circular.length }} 个文件</span>
                    </div>
                    <div class="circular-summary">
                      影响范围：{{ circular.impactScope }} 个文件
                    </div>
                  </div>
                  <div class="header-actions">
                    <el-button
                      type="text"
                      :icon="expanded[circular.id] ? ArrowUp : ArrowDown"
                      @click="toggleExpanded(circular.id)"
                    >
                      {{ expanded[circular.id] ? '收起' : '展开' }}
                    </el-button>
                  </div>
                </div>

                <!-- 展开的详细信息 -->
                <el-collapse-transition>
                  <div v-if="expanded[circular.id]" class="circular-details">
                    <!-- 循环路径 -->
                    <div class="path-section">
                      <h5>🛤️ 循环路径</h5>
                      <div class="path-flow">
                        <div
                          v-for="(path, pathIndex) in circular.path"
                          :key="pathIndex"
                          class="path-item"
                        >
                          <div class="path-step">
                            <div class="step-number">{{ pathIndex + 1 }}</div>
                            <div class="step-content">
                              <div class="file-from">
                                <el-tooltip :content="path.from" placement="top">
                                  <span class="file-name">{{ simplifyPath(path.from) }}</span>
                                </el-tooltip>
                              </div>
                              <div class="dependency-info">
                                <el-icon class="arrow-icon"><ArrowRight /></el-icon>
                                <el-tag
                                  :type="getDependencyTypeColor(path.dependencyType)"
                                  size="mini"
                                >
                                  {{ getDependencyTypeText(path.dependencyType) }}
                                </el-tag>
                                <span v-if="path.isDynamic" class="dynamic-tag">动态</span>
                              </div>
                              <div class="file-to">
                                <el-tooltip :content="path.to" placement="top">
                                  <span class="file-name">{{ simplifyPath(path.to) }}</span>
                                </el-tooltip>
                              </div>
                              <div v-if="path.imports && path.imports.length" class="imports-info">
                                <span class="imports-label">导入：</span>
                                <el-tag
                                  v-for="imp in path.imports.slice(0, 3)"
                                  :key="imp"
                                  size="mini"
                                  type="info"
                                >
                                  {{ imp }}
                                </el-tag>
                                <span v-if="path.imports.length > 3" class="more-imports">
                                  +{{ path.imports.length - 3 }} 更多
                                </span>
                              </div>
                            </div>
                          </div>
                          <div v-if="pathIndex < circular.path.length - 1" class="path-connector">
                            <el-icon><ArrowDown /></el-icon>
                          </div>
                        </div>
                        <!-- 回到起点的箭头 -->
                        <div class="path-back-connector">
                          <el-icon class="back-arrow"><RefreshLeft /></el-icon>
                          <span class="back-text">形成循环</span>
                        </div>
                      </div>
                    </div>

                    <!-- 解决方案建议 -->
                    <div class="suggestions-section">
                      <h5>💡 解决方案建议</h5>
                      <ul class="suggestions-list">
                        <li
                          v-for="(suggestion, sugIndex) in circular.suggestions"
                          :key="sugIndex"
                          class="suggestion-item"
                        >
                          {{ suggestion }}
                        </li>
                      </ul>
                    </div>
                  </div>
                </el-collapse-transition>
              </el-card>
            </div>
          </div>
        </div>

        <!-- 优化建议总结 -->
        <div class="optimization-summary">
          <h4>🎯 整体优化建议</h4>
          <div class="summary-content">
            <el-alert
              v-if="highSeverityCount > 0"
              title="优先处理高危险循环依赖"
              :description="`发现 ${highSeverityCount} 个高危险等级的循环依赖，建议优先解决这些问题以降低项目风险。`"
              type="error"
              :closable="false"
              show-icon
            />

            <div class="general-suggestions">
              <h5>🔧 常用解决策略：</h5>
              <ul class="strategy-list">
                <li><strong>依赖注入：</strong>通过依赖注入容器管理对象的创建和依赖关系</li>
                <li><strong>接口抽象：</strong>引入接口层，解耦具体实现之间的直接依赖</li>
                <li><strong>事件驱动：</strong>使用事件系统替代直接的方法调用</li>
                <li><strong>代码重构：</strong>提取公共逻辑到独立模块，减少交叉依赖</li>
                <li><strong>架构调整：</strong>重新设计模块结构，确保依赖关系的单向性</li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, type Ref } from 'vue';
import {
  ArrowDown,
  ArrowUp,
  ArrowRight,
  Refresh,
  RefreshLeft
} from '@element-plus/icons-vue';
import { AnalysisDataService } from '../services/analysis-data';
import type { ICircularDependency } from '../types/analysis';

// 响应式数据
const loading: Ref<boolean> = ref(true);
const circularDependencies: Ref<ICircularDependency[]> = ref([]);
const expanded: Ref<Record<string, boolean>> = ref({});
const selectedSeverity: Ref<string> = ref('');
const selectedType: Ref<string> = ref('');

const analysisService = AnalysisDataService.getInstance();

/**
 * 总影响文件数
 */
const totalAffectedFiles = computed((): number => {
  const allFiles = new Set<string>();
  circularDependencies.value.forEach(circular => {
    circular.files.forEach(file => allFiles.add(file));
  });
  return allFiles.size;
});

/**
 * 高危险等级循环依赖数量
 */
const highSeverityCount = computed((): number => {
  return circularDependencies.value.filter(c => c.severity === 'high').length;
});

/**
 * 最长循环依赖链长度
 */
const maxCircularLength = computed((): number => {
  return Math.max(...circularDependencies.value.map(c => c.length), 0);
});

/**
 * 过滤后的循环依赖列表
 */
const filteredCircularDependencies = computed((): ICircularDependency[] => {
  let filtered = circularDependencies.value;

  if (selectedSeverity.value) {
    filtered = filtered.filter(c => c.severity === selectedSeverity.value);
  }

  if (selectedType.value) {
    filtered = filtered.filter(c => c.type === selectedType.value);
  }

  // 按危险等级排序：high > medium > low
  const severityOrder = { high: 3, medium: 2, low: 1 };
  return filtered.sort((a, b) => severityOrder[b.severity] - severityOrder[a.severity]);
});

/**
 * 简化文件路径显示
 */
const simplifyPath = (filePath: string): string => {
  if (!filePath) return '';

  // 取文件名和上一级目录
  const parts = filePath.split('/');
  if (parts.length <= 2) return filePath;

  const fileName = parts[parts.length - 1];
  const parentDir = parts[parts.length - 2];

  return `${parentDir}/${fileName}`;
};

/**
 * 获取危险等级样式类
 */
const getSeverityClass = (severity: string): string => {
  return `severity-${severity}`;
};

/**
 * 获取危险等级标签类型
 */
const getSeverityTagType = (severity: string): string => {
  const types: Record<string, string> = { high: 'danger', medium: 'warning', low: 'info' };
  return types[severity] || 'info';
};

/**
 * 获取危险等级文本
 */
const getSeverityText = (severity: string): string => {
  const texts: Record<string, string> = { high: '高危险', medium: '中危险', low: '低危险' };
  return texts[severity] || '未知';
};

/**
 * 获取类型标签类型
 */
const getTypeTagType = (type: string): string => {
  return type === 'file' ? 'primary' : 'success';
};

/**
 * 获取类型文本
 */
const getTypeText = (type: string): string => {
  const texts: Record<string, string> = { file: '文件间', package: '包间' };
  return texts[type] || '未知';
};

/**
 * 获取依赖类型颜色
 */
const getDependencyTypeColor = (type: string): string => {
  const colors: Record<string, string> = {
    local: 'primary',
    package: 'success',
    workspace: 'warning',
    root: 'danger'
  };
  return colors[type] || 'info';
};

/**
 * 获取依赖类型文本
 */
const getDependencyTypeText = (type: string): string => {
  const texts: Record<string, string> = {
    local: '本地',
    package: 'NPM',
    workspace: '工作空间',
    root: '根目录'
  };
  return texts[type] || '未知';
};

/**
 * 切换展开状态
 */
const toggleExpanded = (id: string): void => {
  expanded.value[id] = !expanded.value[id];
};

/**
 * 加载循环依赖数据
 */
const loadCircularDependencies = async (): Promise<void> => {
  try {
    loading.value = true;

    // 检查是否已有数据
    let currentData = analysisService.getCurrentAnalysisData();

    if (!currentData) {
      // 加载数据（路径从环境变量获取）
      await analysisService.loadAnalysisData();
      currentData = analysisService.getCurrentAnalysisData();
    }

    if (currentData && currentData.circularDependencies) {
      circularDependencies.value = currentData.circularDependencies;
    } else {
      // 如果没有循环依赖数据，生成模拟数据用于演示
      circularDependencies.value = generateMockCircularDependencies();
    }
  } catch (error) {
    console.error('加载循环依赖数据失败:', error);
    circularDependencies.value = [];
  } finally {
    loading.value = false;
  }
};

/**
 * 生成模拟循环依赖数据（用于演示）
 */
const generateMockCircularDependencies = (): ICircularDependency[] => {
  // 如果统计中没有循环依赖，返回空数组
  const currentData = analysisService.getCurrentAnalysisData();
  if (!currentData || currentData.statistics.circularDependencies === 0) {
    return [];
  }

  // 生成模拟数据用于演示功能
  return [
    {
      id: 'circular-1',
      files: ['src/components/UserCard.vue', 'src/services/UserService.ts', 'src/stores/UserStore.ts'],
      length: 3,
      type: 'file',
      path: [
        {
          from: 'src/components/UserCard.vue',
          to: 'src/services/UserService.ts',
          dependencyType: 'local',
          imports: ['getUserInfo', 'updateUser'],
          isDynamic: false,
          lineNumber: 15
        },
        {
          from: 'src/services/UserService.ts',
          to: 'src/stores/UserStore.ts',
          dependencyType: 'local',
          imports: ['userState', 'setCurrentUser'],
          isDynamic: false,
          lineNumber: 8
        },
        {
          from: 'src/stores/UserStore.ts',
          to: 'src/components/UserCard.vue',
          dependencyType: 'local',
          imports: ['UserCard'],
          isDynamic: true,
          lineNumber: 42
        }
      ],
      severity: 'high',
      suggestions: [
        '将 UserCard 组件中的业务逻辑提取到独立的 composable 中',
        '使用事件总线替代 UserStore 对组件的直接引用',
        '考虑将 UserService 设计为纯函数，移除对 Store 的依赖',
        '引入依赖注入容器管理组件间的依赖关系'
      ],
      impactScope: 12
    }
  ];
};

/**
 * 重新加载数据
 */
const reload = async (): Promise<void> => {
  expanded.value = {};
  await loadCircularDependencies();
};

// 组件挂载时加载数据
onMounted(() => {
  loadCircularDependencies();
});
</script>

<style scoped>
.circular-dependency-panel {
  margin-bottom: 20px;
}

.panel-card {
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}

.header-left h3 {
  margin: 0 0 8px 0;
  color: #303133;
  font-size: 18px;
  font-weight: 600;
}

.header-subtitle {
  margin: 0;
  color: #909399;
  font-size: 14px;
  line-height: 1.4;
}

.header-actions {
  display: flex;
  gap: 8px;
}

.loading-container, .no-data-container {
  padding: 20px;
}

.panel-content {
  padding: 10px 0;
}

/* 概览统计样式 */
.overview-section {
  margin-bottom: 32px;
}

.stats-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 16px;
}

.stat-card {
  display: flex;
  align-items: center;
  padding: 20px;
  border-radius: 8px;
  transition: all 0.3s ease;
  cursor: help;
  border-left: 4px solid;
}

.stat-card.danger {
  background: linear-gradient(135deg, #fff1f0 0%, #ffebee 100%);
  border-left-color: #f5222d;
}

.stat-card.warning {
  background: linear-gradient(135deg, #fffbf0 0%, #fff7e6 100%);
  border-left-color: #fa8c16;
}

.stat-card.severe {
  background: linear-gradient(135deg, #fff2f0 0%, #ffeaea 100%);
  border-left-color: #cf1322;
}

.stat-card.info {
  background: linear-gradient(135deg, #f6ffed 0%, #f0f9e8 100%);
  border-left-color: #52c41a;
}

.stat-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
}

.stat-icon {
  font-size: 28px;
  margin-right: 16px;
  min-width: 40px;
  text-align: center;
}

.stat-info {
  flex: 1;
}

.stat-value {
  font-size: 28px;
  font-weight: 700;
  color: #303133;
  line-height: 1;
  margin-bottom: 6px;
}

.stat-label {
  font-size: 13px;
  color: #909399;
  font-weight: 500;
}

/* 循环依赖列表样式 */
.circular-list-section {
  margin-bottom: 32px;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding: 16px 0;
  border-bottom: 1px solid #ebeef5;
}

.section-header h4 {
  margin: 0;
  color: #303133;
  font-size: 16px;
  font-weight: 600;
}

.filter-controls {
  display: flex;
  gap: 12px;
}

.circular-items {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.circular-card {
  border-radius: 8px;
  border: 1px solid #ebeef5;
  transition: all 0.3s ease;
}

.circular-card:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.circular-card.severity-high {
  border-left: 4px solid #f5222d;
}

.circular-card.severity-medium {
  border-left: 4px solid #fa8c16;
}

.circular-card.severity-low {
  border-left: 4px solid #52c41a;
}

.circular-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}

.circular-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.circular-index {
  font-weight: 600;
  color: #606266;
  font-size: 16px;
}

.circular-length, .circular-summary {
  font-size: 14px;
  color: #909399;
}

.circular-details {
  border-top: 1px solid #ebeef5;
  padding-top: 20px;
  margin-top: 16px;
}

/* 路径流程样式 */
.path-section h5 {
  margin: 0 0 16px 0;
  color: #303133;
  font-size: 15px;
  font-weight: 600;
}

.path-flow {
  background: #fafafa;
  border-radius: 6px;
  padding: 20px;
  position: relative;
}

.path-item {
  margin-bottom: 16px;
}

.path-step {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.step-number {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  background: #409eff;
  color: white;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 600;
  margin-top: 4px;
}

.step-content {
  flex: 1;
  background: white;
  border-radius: 6px;
  padding: 12px;
  border: 1px solid #e4e7ed;
}

.file-from, .file-to {
  font-weight: 500;
  color: #303133;
  margin-bottom: 6px;
}

.file-name {
  background: #f0f2f5;
  padding: 2px 6px;
  border-radius: 3px;
  font-family: 'Monaco', 'Consolas', monospace;
  font-size: 13px;
}

.dependency-info {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 8px 0;
}

.arrow-icon {
  color: #409eff;
  font-size: 16px;
}

.dynamic-tag {
  font-size: 11px;
  color: #fa8c16;
  background: #fff7e6;
  padding: 1px 4px;
  border-radius: 2px;
  border: 1px solid #ffd591;
}

.imports-info {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 8px;
}

.imports-label {
  font-size: 12px;
  color: #909399;
}

.more-imports {
  font-size: 12px;
  color: #909399;
}

.path-connector {
  display: flex;
  justify-content: center;
  color: #409eff;
  margin: 8px 0;
}

.path-back-connector {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px dashed #d9d9d9;
  color: #f5222d;
  font-size: 14px;
  font-weight: 500;
}

.back-arrow {
  font-size: 18px;
}

/* 建议样式 */
.suggestions-section {
  margin-top: 24px;
}

.suggestions-section h5 {
  margin: 0 0 12px 0;
  color: #303133;
  font-size: 15px;
  font-weight: 600;
}

.suggestions-list {
  margin: 0;
  padding-left: 20px;
}

.suggestion-item {
  color: #606266;
  line-height: 1.6;
  margin-bottom: 8px;
}

/* 优化建议总结样式 */
.optimization-summary {
  border-top: 1px solid #ebeef5;
  padding-top: 24px;
}

.optimization-summary h4 {
  margin: 0 0 16px 0;
  color: #303133;
  font-size: 16px;
  font-weight: 600;
}

.summary-content {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.general-suggestions h5 {
  margin: 0 0 12px 0;
  color: #303133;
  font-size: 15px;
  font-weight: 600;
}

.strategy-list {
  margin: 0;
  padding-left: 20px;
}

.strategy-list li {
  color: #606266;
  line-height: 1.6;
  margin-bottom: 8px;
}

.strategy-list strong {
  color: #303133;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .stats-cards {
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  }

  .stat-value {
    font-size: 24px;
  }

  .section-header {
    flex-direction: column;
    gap: 16px;
    align-items: flex-start;
  }

  .filter-controls {
    width: 100%;
    justify-content: space-between;
  }

  .circular-header {
    flex-direction: column;
    gap: 12px;
  }

  .step-content {
    padding: 8px;
  }

  .path-step {
    flex-direction: column;
    gap: 8px;
  }
}
</style>
